home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / psp.pas < prev    next >
Pascal/Delphi Source File  |  1986-09-10  |  6KB  |  147 lines

  1. {
  2.    USING THE PROGRAM SEGMENT PREFIX (PSP) AS
  3.          A TURBO PASCAL RECORD
  4.  
  5.       GARRY J. VASS [72307,3311]
  6.  
  7.   The program segement prefix is created by DOS
  8.   whenever a program is initiated.  It is 256 decimal
  9.   bytes (100 hexidecimal bytes) long and contains a
  10.   mixed-bag of information that can be used by a Turbo
  11.   program.  Some of the information in the PSP has
  12.   been made obsolete by:
  13.  
  14.            1.  New releases of DOS; and
  15.            2.  New releases of Turbo Pascal.
  16.  
  17.   For example, location 80 hex (128 decimal) contains
  18.   the length of the command tail.  Locations 81 hex
  19.   and beyond contain the tail itself (the "command
  20.   tail", by the way, are the parameters passed to
  21.   a program.  In the case of "format" the tail con-
  22.   tains a drive specification, system option, and
  23.   label option, such as, "a:/s/v".).  The old days
  24.   of de-coding the command tail are gone, however,
  25.   replaced by Turbo's PARAMSTR(1), PARAMSTR(2), etc.
  26.   functions.
  27.  
  28.   The File Control Blocks (FCB) went out with DOS 3,
  29.   although it is still possible to use them.
  30.  
  31.   But several interesting items remain that can be
  32.   found conveniently only in the PSP:
  33.  
  34.          1.  The address of the environment string; and
  35.          2.  The amount of memory available.
  36.  
  37.   The segment address of the environment string is located
  38.   at PSP address 2C hex (44 decimal).  This is equivalent
  39.   to absolute address CSEG:002C.  (NOTE:  If you are using
  40.   debug, pepores, corelook, etc to check this out, remember
  41.   that it will appear in low-byte-followed-by-high-byte
  42.   format.)
  43.  
  44.   Decoding the environment string works as follows:
  45.  
  46.          1.  Set Eseg to MEM[Cseg:2C], or PSP.ENVIRONMENT_SEGMENT.
  47.              Start with offset address zero;
  48.          2.  Concatenate the character value of
  49.              the byte at Eseg:offset to a character string;
  50.          3.  Increment the offset address and
  51.              repeat step 2.
  52.          4.  If the byte at Eseg:offset is equal to zero,
  53.              then one string has been found.
  54.          5.  If two consequtive bytes are equal to zero,
  55.              then you have reached the end of the environment
  56.              area.
  57.  
  58.   Normally, the environment strings are 10 hex paragraphs long
  59.   (or 160 decimal bytes).  Some folks patch command.com and others
  60.   use config.sys options to reset this value, and as Turbo programmers,
  61.   we must accomodate them.  (The easiest way to give yourself more
  62.   environment space is to use the SHELL statement in your config.sys
  63.   file.  For example:  SHELL=C:\COMMAND.COM /P /E:20, will give you
  64.   20 hex paragraphs.)  This, combined with Turbo's limitation of
  65.   255 decimal bytes for a maximum string length, means that a REPEAT/
  66.   UNTIL construct is necessary.
  67.  
  68.   Another item worth checking is the memory size DOS thinks it has.
  69.   This is given in Cseg:0002, or PSP.MEMORY_SIZE_IN_PARAGRAPHS.
  70.  
  71.   The functions, ENVIRONMENT and MEMORY, provide at least one way
  72.   of getting at these values.
  73.  
  74. }
  75. PROGRAM PSP;
  76. TYPE
  77.     ANYSTRING = STRING[255];
  78.     PSPAREA = RECORD
  79.                     INT_20_INSTRUCTION         :INTEGER;
  80.                     MEMORY_SIZE_IN_PARAGRAPHS  :INTEGER;
  81.                     RESERVED_BYTE              :BYTE;
  82.                     CALL_TO_DOS                :ARRAY[1..05] OF BYTE;
  83.                     TERMINATE_VECTOR           :ARRAY[1..02] OF INTEGER;
  84.                     BREAK_VECTOR               :ARRAY[1..02] OF INTEGER;
  85.                     ERROR_VECTOR               :ARRAY[1..02] OF INTEGER;
  86.                     USED_BY_DOS                :ARRAY[1..22] OF BYTE;
  87.                     ENVIRONMENT_SEGMENT        :INTEGER;
  88.                     DOS_WORK_AREA              :ARRAY[1..34] OF BYTE;
  89.                     INT21_INSTRUCTIONS         :ARRAY[1..03] OF BYTE;
  90.                     MORE_RESERVED              :INTEGER;
  91.                     FCB_1_EXTENSION            :ARRAY[1..07] OF BYTE;
  92.                     FCB_1                      :ARRAY[1..09] OF BYTE;
  93.                     FCB_2_EXTENSION            :ARRAY[1..07] OF BYTE;
  94.                     FCB_2                      :ARRAY[1..20] OF BYTE;
  95.                     PARAMETER_LENGTH           :BYTE;
  96.                     PARAMETERS                 :ARRAY[1..127] OF CHAR;
  97.               END;
  98. VAR
  99.    PSP    :PSPAREA ABSOLUTE CSEG:$0000;
  100.    I      :INTEGER;
  101.    OFFSET :INTEGER;
  102.    MORE   :BOOLEAN;
  103.  
  104. FUNCTION  REALNUMBER(R:INTEGER):REAL;
  105. BEGIN
  106.      IF R < 0 THEN REALNUMBER := 65536.0 + R
  107.               ELSE REALNUMBER := R;
  108. END;
  109.  
  110. FUNCTION ENVIRONMENT(SEGMENT:INTEGER;VAR OFF:INTEGER; VAR MORE:BOOLEAN):ANYSTRING;
  111. {GET THE NEXT ASCIIZ STRING FROM THE ENVIRONMENT}
  112. VAR
  113.     T       : ANYSTRING;
  114.     OFFSET  : INTEGER;
  115. BEGIN
  116.      T      := '';
  117.      OFFSET := OFF;
  118.      REPEAT
  119.            T      := T + CHR(MEM[SEGMENT:OFFSET]);
  120.            OFFSET :=     SUCC(OFFSET);
  121.      UNTIL (MEM[SEGMENT:OFFSET] = 0);
  122.     IF (MEM[SEGMENT:OFFSET + 0] = 0) AND
  123.        (MEM[SEGMENT:OFFSET + 1] = 0) THEN MORE := FALSE
  124.                                      ELSE MORE := TRUE;
  125.     ENVIRONMENT := T;
  126.     OFF := OFFSET;
  127. END;
  128.  
  129. FUNCTION MEMORY(MEMORYSIZE:INTEGER):REAL;
  130. BEGIN
  131.      MEMORY := REALNUMBER(MEMORYSIZE) * 16;
  132. END;
  133.  
  134. BEGIN
  135.      OFFSET := 0;
  136.      REPEAT
  137.           WRITELN('ENVIRONMENT STRING = ',ENVIRONMENT(PSP.ENVIRONMENT_SEGMENT,OFFSET,MORE));
  138.      UNTIL NOT MORE;
  139.      WRITELN('DOS THINKS IT HAS ',MEMORY(PSP.MEMORY_SIZE_IN_PARAGRAPHS):10:0,' BYTES AVAILABLE');
  140. END.
  141.  
  142. y:
  143.  
  144.            1.  New releases of DOS; and
  145.            2.  New releases of Turbo Pascal.
  146.  
  147.   For examp